﻿using HzyScanDiService.Models;
using System;
using System.Collections.Generic;

namespace HzyScanDiService.Attributes
{
    /// <summary>
    /// aop 基础特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public abstract class AopBaseAttribute : Attribute
    {
        /// <summary>
        /// di 类型 属性为 null 时 默认使用标记类 为服务类型 动态代理类 为实现类
        /// </summary>
        public Type ServiceTypeInfo { get; set; } = null;

        /// <summary>
        /// di 注入 服务类型
        /// </summary>
        public DiServiceTypeEnum DiServiceType { get; set; } = DiServiceTypeEnum.Transient;

        /// <summary>
        /// Aop 特性类型 默认类型：AopBaseAttribute
        /// </summary>
        public Type AopAttributeType { get; set; } = typeof(AopBaseAttribute);

        /// <summary>
        /// 获取服务类型信息
        /// </summary>
        /// <returns></returns>
        public Type GetDiServiceTypeInfo() => ServiceTypeInfo;

        /// <summary>
        /// 获取服务 di 类型
        /// </summary>
        /// <returns></returns>
        public DiServiceTypeEnum GetDiServiceType() => this.DiServiceType;

        /// <summary>
        /// 函数执行前
        /// </summary>
        /// <param name="classContext">拦截类的上下文信息</param>
        /// <param name="parameter">函数入参参数信息</param>
        /// <param name="methodName">函数名称</param>
        public abstract void Before(ClassContext classContext, Dictionary<string, object> parameter, string methodName);

        /// <summary>
        /// 函数执行后
        /// </summary>
        /// <param name="classContext">拦截类的上下文信息</param>
        /// <param name="result">函数执行后结果</param>
        /// <param name="methodInfo">函数名称</param>
        public abstract void After(ClassContext classContext, object result, string methodName);

        /// <summary>
        /// 函数执行异常事件
        /// </summary>
        /// <param name="classContext">ClassContext</param>
        /// <param name="exception">Exception</param>
        /// <param name="methodName">string</param>
        public Action<ClassContext, Exception, string> ExceptionEvent = null;

    }

}
